package dynamicloader.windy.com.dynamicloader;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import com.windy.dynamicloader.DynamicInterface;

import junit.framework.Test;

import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import dalvik.system.DexClassLoader;

/**
 * Created by admin on 2015/12/24.
 */
public class DynamicLoaderActivity extends Activity implements View.OnClickListener {

    private static final String TAG = "DynamicLoaderActivity";
    private boolean isLoadSuccess = false;
    private DynamicInterface dynamicClass = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dynamic_loader);

        findViewById(R.id.btn_load_from_sdcard).setOnClickListener(this);
        findViewById(R.id.btn_load_from_apk).setOnClickListener(this);
        findViewById(R.id.btn_invoke).setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_load_from_sdcard: {
                loadDynamicClassFromSdcard();
            }
            break;

            case R.id.btn_load_from_apk: {
                loadDynamicClassFromApkFile();
            }
            break;

            case R.id.btn_invoke: {
                invokeDynamicMethod();
            }
            break;
        }
    }

    private void invokeDynamicMethod() {
        if (isLoadSuccess && dynamicClass != null) {
            Toast.makeText(this,dynamicClass.helloworld(),Toast.LENGTH_SHORT).show();
        }
    }

    private void loadDynamicClassFromApkFile() {
        String classPath = Environment.getExternalStorageDirectory() + File.separator + "TestApk.apk";
        File file = new File(classPath);

        if (file.exists()) {
            DexClassLoader classloader = new DexClassLoader(file.getAbsolutePath(),getFilesDir().toString(),null
            ,getClassLoader());
            Class tmpClass = null;
            try {
                tmpClass = classloader.loadClass("com.example.testapk.TestActivity");

                try {
                    Object object = tmpClass.newInstance();

                    try {
                        Method method = tmpClass.getMethod("helloworld",null);
                        try {
                            Object returnVal = method.invoke(object,null);
                            Toast.makeText(this,returnVal.toString(), Toast.LENGTH_SHORT).show();
                        } catch (InvocationTargetException e) {
                            e.printStackTrace();
                        }
                    } catch (NoSuchMethodException e) {
                        e.printStackTrace();
                    }
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }


            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        } else {
            Toast.makeText(this, "apk file does not exist.", Toast.LENGTH_SHORT).show();
        }
    }

    private void loadDynamicClassFromSdcard() {
        String classPath = Environment.getExternalStorageDirectory() + File.separator + "test.jar";
        Log.d(TAG, "classPath is:" + classPath);
        File file = new File(classPath);
        if (file.exists()) {
            DexClassLoader classloader = new DexClassLoader(file.getAbsolutePath().toString(), getFilesDir().toString(), null, getClassLoader());
            try {
                Class tmp = classloader.loadClass("com.windy.dynamicloader.DynamicInstance");
                try {
                    dynamicClass = (DynamicInterface) tmp.newInstance();
                    isLoadSuccess = true;
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        } else {
            Toast.makeText(this, "dex file not found", Toast.LENGTH_SHORT).show();
        }
    }
}

